home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-03-25 | 5.8 KB | 162 lines | [TEXT/PJMM] |
- program sndDemo;
-
- { I spent a hard week getting this demo of the playing of an asynchronous sound to work }
- { in Think Pascal 4.0.2. My main difficulty was that it won't work with the [D] Debug switch set }
- { on the compile options. But the manual doesn't contain all of the necessary information. }
- { Some essential ideas were gleaned from Jim Reekes' pSoundApp example in the DTS folder }
- { of ftp.apple.com. Since it was so touchy, I thought others might benefit from this demo. }
- { }
- { This code is terse. I have stripped out everything but the essentials. It should be used }
- { in conjuntion with chapter 22 of volume VI of Inside Macintosh. I have deliberately left }
- { out all error checking so as to not obscure the essential code. Although in all my testing }
- { I never saw an error that wasn't a result of my stupidity or ignorance. I have included a }
- { few extra inline procedure declarations to make it easier to build this demo into a real program. }
- { }
- { To play an asynchronous sound - that is, a sound that plays while other things are happening, }
- { one must define a callBack procedure. This procedure can't do much because it will be invoked }
- { at interrupt time and won't have access to your normal program environment. To access your }
- { global variables, you must restore register A5. Most of the callBack code is concerned with }
- { restoring A5; and all the callback procedure does is set a switch 'sndProgress := 2' so that you }
- { can tell (elsewhere) that the sound has finished. }
- { }
- { Two global variables are needed: }
- { - The integer sndProgress is meant to have the value 0 when no sound is playing, 1 when a sound}
- { is playing, and 2 when a sound has finished but the resources haven't been released yet. }
- { - The sndChannelPtr mySndChannel is given a value when a sound channel is allocated in the }
- { routine that starts the sound playing (aSyncStartPlay), and is needed to dispose of the channel }
- { when the sound has completed and must be disposed (aSyncEndPlay). }
- { }
- { If you use these routines to play async sounds, you will want a line of code in your main}
- { event loop to dispose of the channel and sound handle as soon as the sound has completed:}
- { if sndProgress = 2 then }
- { aSyncEndPlay(sndChannel); }
- { }
- { What this demo program does, is start the sound playing and then count until the sound is done. }
- { The count is written to the text window. It does this five times. You must open the window manually }
- { and place it strategically if you want to watch the counting as the sound is played. }
- { ------------------------------------------------------------------------------------------ }
- { Marv Westrom }
- { Mathematics and Science Education (Computing Studies Education) }
- { The University of British Columbia }
- { Vancouver, B.C. Canada V6T 1Z4 }
- { ------------------------------------------------------------------------------------------ }
- { March 24, 1993.}
- { ------------------------------------------------------------------------------------------ }
-
- const
- stdQLength = 128;
- NoSynth = 0; { no specified synth for channel }
- InitNone = 0; { no specified init parameters for channel }
-
- type
- SndCommand = packed record
- cmd: INTEGER;
- param1: INTEGER;
- param2: LONGINT;
- end;
- Time = LONGINT; { in half milliseconds }
- SndChannelPtr = ^SndChannel;
- SndChannel = packed record
- nextChan: SndChannelPtr;
- firstMod: Ptr;{ reserved for the Sound Manager }
- callBack: ProcPtr;
- userInfo: LONGINT;
- wait: Time; { The following is for internal Sound Manager use only.}
- cmdInProgress: SndCommand;
- flags: INTEGER;
- qLength: INTEGER;
- qHead: INTEGER;
- qTail: INTEGER;
- queue: array[1..stdQLength] of SndCommand;
- end;
-
- var { necessary globals }
- mySndChannel: SndChannelPtr;
- sndProgress: integer;
-
- function SndDisposeChannel (chan: sndChannelPtr; quietNow: BOOLEAN): OSErr;
- inline
- $A801;
- function SndDoCommand (chan: sndChannelPtr; cmd: SndCommand; noWait: BOOLEAN): OSErr;
- inline
- $A803;
- function SndDoImmediate (chan: sndChannelPtr; cmd: SndCommand): OSErr;
- inline
- $A804;
- function SndPlay (chan: SndChannelPtr; sndHdl: Handle; async: BOOLEAN): OSErr;
- inline
- $A805;
- function SndNewChannel (var chan: SndChannelPtr; synth: INTEGER; init: LONGINT; userRoutine: ProcPtr): OSErr;
- inline
- $A807;
- function setCurrentA5: longint;
- inline
- $2E8D, $2A78, $0904;
- function setA5 (newA5: longint): longint;
- inline
- $2F4D, $0004, $2A5F;
-
- procedure myCallBack (Chan: sndChannelPtr; cmd: sndCommand);
- var
- myA5: longint;
- begin
- if cmd.param1 = 99 then
- begin
- myA5 := setA5(cmd.param2);
- sndProgress := 2;
- myA5 := SetA5(myA5);
- end;
- end;
-
- procedure aSyncStartPlay (sndH: handle);
- var
- mySndCmd: sndCommand;
- myErr: OSErr;
- begin
- LoadResource(sndH);
- moveHHi(sndH);
- Hlock(sndH);
- mySndChannel := nil;
- myErr := SndNewChannel(mySndChannel, NoSynth, InitNone, @myCallBack);
- myErr := sndPlay(mySndChannel, sndH, true);
- sndProgress := 1;
- mySndCmd.cmd := 13; { callBackCmd }
- mySndCmd.param1 := 99; { arbitrary code to check myCallback }
- mySndCmd.param2 := setCurrentA5;
- myErr := sndDoCommand(mySndChannel, mySndCmd, false);
- end;
-
- procedure aSyncEndPlay (sndH: handle);
- var
- mySndCmd: sndCommand;
- myErr: OSErr;
- begin
- mySndCmd.cmd := 3; { quietCmd }
- myErr := sndDoCommand(mySndChannel, mySndCmd, false);
- myErr := sndDisposeChannel(mySndChannel, true);
- HUnlock(sndH);
- sndProgress := 0;
- end;
-
- var
- sndHiThere: handle;
- i, times: integer;
-
- begin
- sndProgress := 0;
- sndHiThere := getnamedresource('snd ', 'Hi There');
- for times := 1 to 5 do
- begin
- writeln;
- writeln('Hi there ', times : 2);
- aSyncStartPlay(sndHiThere);
- i := 0;
- repeat
- i := i + 1;
- write(i : 3);
- if (i mod 25) = 0 then
- writeln;
- until sndProgress = 2;
- aSyncEndplay(sndHiThere);
- end;
- end.